﻿using AppData;
using ServerShared.AppData;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerShared
{
    public class TableHelper
    {
        public static device FindInDeviceTable(string uuid)
        {
            if (string.IsNullOrEmpty(uuid))
            {
                GameDebug.LogError($"FindInDeviceTable  uuid empty");
                return null;
            }

            return MysqlFunction.FindInTable<device>(ServerConfig.DBShared, SqlTable.device, "uuid", uuid);
        }
        public static users FindInUserTable(long deviceId)
        {
            string database = users.GetUserDatabaseWithDeviceId(deviceId);
            long userTableId = users.DeviceId2UserTableId(deviceId);

            GameDebug.Log($"userId:{deviceId}  所在数据库是：{database}  userTableId:{userTableId}");

            return MysqlFunction.FindInTable<users>(database, SqlTable.users, "id", userTableId.ToString());
        }
        public static User UserTable2User(long deviceId, users userTable)
        {
            //texture[] textureTable = TableHelper.FindInTextureTable(existDevice.id);
            Tex icon = TextureSaver.LoadUserTexture(deviceId, 1);

            return ReadUserTable(deviceId, userTable, icon);
        }

        //public static User ReadUserTable(string database, users ut, Tex icon)
        //{
        //    long deviceId = users.UserTableId2DeviceId(database, ut.id);
        //    return ReadUserTable(deviceId, ut, icon);
        //}

        public static User ReadUserTable(long deviceId, users ut, Tex icon)
        {
            MiniUserInfo userInfo = UserTable2UserInfo(deviceId, ut, icon);

            User user = new User(deviceId, ut.nickname, "", ut.max_lv, ut.coin, ut.diamond, ut.is_robot > 0, ut.login_day,
                users.ObtainedLoginBonusString2List(ut.obtain_login_bonus_day), users.String2LongList(ut.friends), userInfo);//, petIds, usedSkinIndexes, powers, propertyProportions);

          
            user.myFollows = users.String2LongList(ut.myfollows);
            user.followers = users.String2LongList(ut.followers);

            //user获取个人动态数据。登录先不发
            moments[] momentsArr = TableHelper.FindInMomentsTableWithUserID(deviceId);

            List<Moment> moments = new List<Moment>(momentsArr.Length);
            for (int i = 0; i < momentsArr.Length; i++)
            {
                moments.Add(Table2Moment(momentsArr[i]));
            }
            user.moments = moments;

            user.obtainShareReward = ut.obtain_shared_reward;

            //GameDebug.Log($"tex1:{userInfo.tex1 != null}");
            return user;
        }

        public static MiniUserInfo GetUserInfoWithUserId(long deviceId, bool onlyIcon = false)
        {
            users ut = TableHelper.FindInUserTable(deviceId);

            MiniUserInfo userInfo = null;
            if (ut == null)
                return userInfo;

            Tex icon = TextureSaver.LoadUserTexture(deviceId, 1);
            userInfo = TableHelper.UserTable2UserInfo(deviceId, ut, icon);

            return userInfo;
        }

        public static MiniUserInfo UserTable2UserInfo(long deviceId, users ut, Tex icon)
        {
            MiniUserInfo userInfo = new MiniUserInfo(deviceId, ut.gender, ut.name,ut.about_me, ut.birth_date,
                ut.location_province, ut.location_city, icon);

            return userInfo;
        }
        #region Book
        public static books FindInBookTable(string id,string name)
        {
            if (string.IsNullOrEmpty(id))
            {
                GameDebug.LogError($"FindInBooksTable  id empty");
                return null;
            }

            var table = MysqlFunction.FindInTable<books>(ServerConfig.DBBook, books.GetBookTable(name), "id", id);
            return table;
        }
        public static books FindInBookTable(string name,string author,string publisher)
        {
            var table = MysqlFunction.FindInTable<books>(ServerConfig.DBBook, books.GetBookTable(name), "name", name,"author",author);
            return table;
        }
        public static books[] FindInBooksTableWithTable(SqlTable table,int maxCount)
        {
            var chatsArr = MysqlFunction.SelectRowsInTable<books>(ServerConfig.DBBook, table, maxCount);
  
            return chatsArr;
        }

        public static books[] FindInBooksTableWithName(SqlTable table,string name, int maxCount)
        {
            var chatsArr = MysqlFunction.FindRowsWithContainsInTable<books>(ServerConfig.DBBook, table, "name", name, maxCount);
            return chatsArr.ToArray();
        }
        public static BookInfo Table2Book(books table)
        {
            string genre = books.GetBookGenre(table.name);
            var icon = TextureSaver.LoadBookTexture(table.id, genre);
            BookInfo bookInfo = new BookInfo(table.sub_genre, table.name, table.description, table.author, table.publisher,
                table.publish_date, table.file_ext, icon);
            return bookInfo;
        }

        public static Book[] GetAllBooks(int maxCount)
        {
            List<Book> res = new List<Book>();

            for (int i = (int)SqlTable.books_A; i<= (int)SqlTable.books_Z;i++)
            { 
                var booksTable = FindInBooksTableWithTable((SqlTable)i, maxCount);

                for (int j = 0; j < booksTable.Length; j++)
                {
                    books bookTable = booksTable[j];

                    var newBook = new Book();
                    newBook.id = bookTable.id;
                    newBook.info = Table2Book(bookTable);
                    string genre = books.GetBookGenre(bookTable.name);
                    newBook.contentData = BooksSaver.LoadBook(bookTable.id.ToString(), genre);

                    res.Add(newBook);

                    if (res.Count >= maxCount)
                        return res.ToArray();
                } 
            }
            return res.ToArray();
        }
        public static Book[] GetBooksWithName(SqlTable table,string name, int maxCount)
        {
            var booksTable = FindInBooksTableWithName(table,name, maxCount);

            Book[] res = new Book[booksTable.Length];
            for (int i = 0; i < booksTable.Length; i++)
            {
                books bookTable = booksTable[i];

                var newBook = new Book();
                newBook.id = bookTable.id;
                newBook.info = Table2Book(bookTable);
                string genre = books.GetBookGenre(bookTable.name);
                newBook.contentData = BooksSaver.LoadBook(bookTable.id.ToString(), genre);

                res[i] = newBook;
            }
            return res;
        }

        #endregion

        #region Moment
        public static moments[] FindInMomentsTableWithUserID(long user_id)
        {
            string database = users.GetUserDatabaseWithDeviceId(user_id);

            var arr = MysqlFunction.FindRowsInTable<moments>(database, SqlTable.moments, "uid", user_id.ToString());

            return arr;
        }
        public static moments[] SelectMomentsTableDesc(int num)
        {
            List<moments> tables = new List<moments>();
            for (int dbId = 1; dbId <= 10; dbId++)
            {
                var arr = MysqlFunction.SelectRowsInTableDesc<moments>(users.GetUserDatabaseWithDbId(dbId), SqlTable.moments, num);

                foreach (var table in arr)
                {
                    tables.Add(table);

                    if (tables.Count >= num)
                    {
                        return tables.ToArray();
                    }
                }
            }
            return tables.ToArray();
        }
        public static moments[] SelectMomentsTableDesc(string locationCity, int num)
        {
            return SelectMomentsTableDesc("user_location_city", locationCity, num);
        }
        public static moments[] SelectMomentsTableDesc(string col, string value, int num)
        {
            List<moments> tables = new List<moments>();
            for (int dbId = 1; dbId <= 10; dbId++)
            {
                var arr = MysqlFunction.SelectRowsInTableDesc<moments>(users.GetUserDatabaseWithDbId(dbId), SqlTable.moments, col, value, num);

                foreach (var table in arr)
                {
                    tables.Add(table);

                    if (tables.Count >= num)
                    {
                        return tables.ToArray();
                    }
                }
            }
            return tables.ToArray();
        }

        public static comments FindInCommentTable(long momentUserId, long commentId)
        {
            string database = users.GetUserDatabaseWithDeviceId(momentUserId);
            return MysqlFunction.FindInTable<comments>(database, SqlTable.comments, "id", commentId.ToString());

        }
        public static moments FindInMomentTable(long momentUserId, long momentId)
        {
            string database = users.GetUserDatabaseWithDeviceId(momentUserId);
            return MysqlFunction.FindInTable<moments>(database, SqlTable.moments, "id", momentId.ToString());
        }

        public static Moment Table2Moment(moments table)
        {
            if (table == null)
                return null;

            long deviceId = table.uid;

            Tex tex1 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 1);
            Tex tex2 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 2);
            Tex tex3 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 3);
            Tex tex4 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 4);
            Tex tex5 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 5);
            Tex tex6 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 6);
            Tex tex7 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 7);
            Tex tex8 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 8);
            Tex tex9 = TextureSaver.LoadMomentPhoto(deviceId, table.id, 9);
            Tex[] texes = new[] { tex1, tex2, tex3, tex4, tex5, tex6, tex7, tex8, tex9 };

            List<long> commentIds = users.String2LongList(table.comments);

            List<Comment> commentsArr = new List<Comment>(commentIds.Count);
            for (int j = 0; j < commentIds.Count; j++)
            {
                var commentTable = TableHelper.FindInCommentTable(deviceId, commentIds[j]);
                if (commentTable == null)
                    continue;

                List<SubComment> subComments = null;

                if (!string.IsNullOrEmpty(commentTable.subcomments))
                {
                    subComments = Newtonsoft.Json.JsonConvert.DeserializeObject<List<SubComment>>(commentTable.subcomments);
                }

            
                MiniUserInfo miniUserInfo = TableHelper.GetUserInfoWithUserId(commentTable.uid);

                var comment = new Comment(deviceId, commentTable.moment_id, commentTable.id, miniUserInfo, commentTable.content,
                users.String2LongList(commentTable.likes), commentTable.time, subComments);

                commentsArr.Add(comment);
            }

            var moment = new Moment(deviceId, table.id, table.time, table.content, table.location, table.topic,table.moment_status
                , users.String2LongList(table.likes), commentsArr, texes);

            return moment;

        }
#endregion
    }
}
